﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using System.Threading;

namespace BDSim
{
    [TypeConverter(typeof(PropertySorter))]
    public class MonitorReceiver : BDSimObject, IPPositionEvaluation
    {
        public MonitorReceiver()
        {
            DataProvider.Parent = this;
            DataProvider.DefineCommand();
            this.Menu.ItemsSource = DataProvider.MenuCommandList;
        }

        #region 字段
        private string _Name;
        private MonitorStation _Parent;
        [XmlIgnore]
        public MonitorReceiverDataProvider DataProvider = new MonitorReceiverDataProvider();

        private PosXYZClass _DeltaPos = new PosXYZClass() { X = 0.0, Y = 0.0, Z = 0.0 };//安装位置，界面设置
        private PosENUClass _U_Off = new PosENUClass();  // 接收机在东北天的相位中心偏差（PCO）

        private NodePosVel RecPVECF;//接收机的ECF位置
        [XmlIgnore]
        public ERecType RecType = ERecType.BD;//接收机类型(BD/GPS/GLO/GALILEO)
        [XmlIgnore]
        public List<EFrePoint> RecFre = new List<EFrePoint>() { { EFrePoint.BD_B1 }, { EFrePoint.BD_B2 }, { EFrePoint.BD_B3 } };//接收机频点选择

        int SubGroundSegmentNumFlag = 0;//用于对没有地面站的情况进行提示
        int StaNumFlag = 0;//用于对没有主控站的情况进行提示（有主控站，没列表）
        int MasterStaFlag = 0;//用于对没有主控站个数的情况进行提示
        int EphNumFlag = 0;//用于对没有星历数据的情况进行提示
        int SatNumFlag = 0;//用于对可见卫星数少于4时进行提示

        //随机误差赋值
        [XmlIgnore]
        public CalRan_Input pCalRan_Input;


        #region 监测站观测数据生成
        [XmlIgnore]
        public List<Dictionary<string, List<ObsReceiverOutput>>> AllSatsObsDataDic;
        /// <summary>
        /// 观测截止仰角(0~30)
        /// </summary>
        private double _Elelim = 5;

        private ObsErrFlagClass _ObsErrFlag = new ObsErrFlagClass();
        private double _PseudoRanThH = 0.3;//不超过分米量级，界面设置
        private double _CarrRanThH = 0.003;//不超过毫米量级，界面设置
        private EPositionType _PositionType = EPositionType.最小二乘法;

        #region 观测误差模型控制
        private ESatClkModelType _ObsSatclkModel;//卫星钟模型，界面设置
        private ESatClkModelType _ObsStaclkModel;//地面站钟模型，界面设置
        private IonSimModelType _ObsIonModel;//电离层模型，界面设置
        private ETroModelType _ObsTroModel;//对流层模型，界面设置
        private EMulModelType _ObsMulModel;//多路径模型，界面设置
        private ERelModelType _ObsRelModel;//相对论模型，界面设置
        private EOffModelType _ObsOffModel;//相位中心偏移模型，界面设置
        #endregion

        /// <summary>
        ///List<ObsReceiverOutput>为单个时刻单星多频点观测值，
        ///Dictionary<string, List<ObsReceiverOutput>>为单个时刻所有卫星多频点观测集
        ///AllSatsObsDataDic为所有可见卫星观测值集
        /// </summary>
        //   public List<Dictionary<string, List<ObsReceiverOutput>>> AllSatsObsDataDic = new List<Dictionary<string, List<ObsReceiverOutput>>>();                

        [XmlIgnore]
        public Dictionary<string, List<ObsReceiverOutput>> SingleTimAllSatsObs = new Dictionary<string, List<ObsReceiverOutput>>();// 单个时刻所有星座所有可见卫星观测值,其中string为卫星名


        Dictionary<EConstellationType, Dictionary<string, List<ObsReceiverOutput>>> Con_SingleTimAllSatsObsDic = new Dictionary<EConstellationType, Dictionary<string, List<ObsReceiverOutput>>>();//分星座存储单个时刻所有可见星观测数据
        [XmlIgnore]
        public List<Dictionary<EConstellationType, Dictionary<string, List<ObsReceiverOutput>>>> ALLObsSatsDataDic_ConType;//分星座系统存储的所有时刻可见星的所有频点观测数据，属性不显示


        Dictionary<EConstellationType, List<EFrePoint>> Con_FresDic = new Dictionary<EConstellationType, List<EFrePoint>>();//分星座存储频点

        [XmlIgnore]
        public Dictionary<ERecType, List<EFrePoint>> RecType_Fre = new Dictionary<ERecType, List<EFrePoint>>();//多模接收机多频点

        #endregion

        #region 监测站定位

        private NodePosVel _FixedPosVelXYZ;   //定位结果

        Dictionary<EConstellationType, PPositionning_Output> RecFixedData;

        DopDLL.DopOutput _DopResult;    //定位精度

        [XmlIgnore]
        public List<SatPredictStatus> SatSpaceParamList = new List<SatPredictStatus>();/// 星空参数列表      

        #region 定位解算误差控制
        private ESatClkModelType _PPSatclkModel;//定位解算使用的卫星钟模型，界面设置
        private EIonModelType _PPIonModel = EIonModelType.EightParam;//定位解算使用的电离层模型，界面设置
        private EMulModelType _PPMulModel;//定位解算使用的多路径模型，界面设置
        private EOffModelType _PPOffModel;//定位解算使用的相位中心偏移模型，界面设置
        //private RanSet _RanModel;
        #endregion

        #endregion

        #region 更新接收机定位评估结果
        [XmlIgnore]
        Action<NodePosVel, NodePosVel, UTCTime, List<SatPredictStatus>, DopDLL.DopOutput> _UpDatePPositionResult;

        #endregion

        #endregion

        #region 属性

        [XmlAttribute, Category("基本信息"), Description("")]
        public string Name
        {
            get { return _Name; }
            set { _Name = value; NotifyPropertyChanged("Name"); }
        }

        [Browsable(false), XmlIgnore]
        public MonitorStation Parent
        {
            get { return _Parent; }
            set { _Parent = value; }
        }

        [Browsable(false), XmlIgnore]
        public NodePosVel FixedPosVelXYZ
        {
            get { return _FixedPosVelXYZ; }
            set { _FixedPosVelXYZ = value; }
        }

        [Browsable(false), XmlIgnore]
        public DopDLL.DopOutput DopResult
        {
            get { return _DopResult; }
            set { _DopResult = value; }
        }

        [DescriptionAttribute("接收机相对于东北天的相位中心偏移量"), CategoryAttribute("基本信息"), PropertyOrder(5)]
        public PosENUClass U_Off
        {
            get { return _U_Off; }
            set { _U_Off = value; }
        }

        /// <summary>
        /// 接收机相对于载体的安装位置
        /// </summary>
        [DescriptionAttribute("接收机相对于载体的安装位置"), CategoryAttribute("基本信息"), PropertyOrder(5)]
        public PosXYZClass DeltaPos
        {
            get { return _DeltaPos; }
            set { _DeltaPos = value; }
        }

        #region 观测误差配置

        [Category("观测数据仿真设置"), Description("截止高度角"), PropertyOrder(2)]
        public double Elelim
        {
            get { return _Elelim; }
            set { _Elelim = value; }
        }

        /// <summary>
        /// 伪距噪声量级，不超过分米量级
        /// </summary>
        [XmlAttribute, DescriptionAttribute("接收机观测数据生成时的伪距噪声量级，不超过分米量级"), Category("观测数据仿真设置"), PropertyOrder(3)]
        public double PseudoRanThH
        {
            get { return _PseudoRanThH; }
            set { _PseudoRanThH = value; }
        }

        /// <summary>
        /// 载波相位噪声量级，不超过毫米量级
        /// </summary>
        [XmlAttribute, DescriptionAttribute("接收机观测数据生成时的载波相位噪声量级，不超过毫米量级"), Category("观测数据仿真设置"), PropertyOrder(4)]
        public double CarrRanThH
        {
            get { return _CarrRanThH; }
            set { _CarrRanThH = value; }
        }

        #region 观测误差开关
        [Category("观测数据仿真设置"), Description("误差控制开关"), PropertyOrder(5)]
        public ObsErrFlagClass ObsErrFlag
        {
            get { return _ObsErrFlag; }
            set { _ObsErrFlag = value; }
        }
        #endregion

        #region 观测误差模型

        /// <summary>
        /// 卫星钟差模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("卫星钟差模型"), DisplayName("SatclkModel"), PropertyOrder(6)]
        public ESatClkModelType ObsSatclkModel
        {
            get { return _ObsSatclkModel; }
            set { _ObsSatclkModel = value; }
        }

        /// <summary>
        /// 地面站钟差模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("地面站钟差模型"), DisplayName("StaclkModel"), PropertyOrder(7)]
        public ESatClkModelType ObsStaclkModel
        {
            get { return _ObsStaclkModel; }
            set { _ObsStaclkModel = value; }
        }


        /// <summary>
        /// 电离层模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("电离层模型"), DisplayName("IonModel"), PropertyOrder(8)]
        public IonSimModelType ObsIonModel
        {
            get { return _ObsIonModel; }
            set { _ObsIonModel = value; }
        }

        /// <summary>
        /// 对流层模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("对流层模型"), DisplayName("TroModel"), PropertyOrder(9)]
        public ETroModelType ObsTroModel
        {
            get { return _ObsTroModel; }
            set { _ObsTroModel = value; }
        }



        /// <summary>
        /// 多路径模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("多路径模型"), DisplayName("MulModel"), PropertyOrder(10)]
        public EMulModelType ObsMulModel
        {
            get { return _ObsMulModel; }
            set { _ObsMulModel = value; }
        }

        /// <summary>
        /// 相对论模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("相对论模型"), DisplayName("RelModel"), PropertyOrder(11)]
        public ERelModelType ObsRelModel
        {
            get { return _ObsRelModel; }
            set { _ObsRelModel = value; }
        }

        /// <summary>
        /// 相位中心偏移模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("相位中心偏移模型"), DisplayName("OffModel"), PropertyOrder(12)]
        public EOffModelType ObsOffModel
        {
            get { return _ObsOffModel; }
            set { _ObsOffModel = value; }
        }

        #endregion

        #endregion

        #region 定位解算设置
        /// <summary>
        /// 定位模式
        /// </summary>
        [XmlAttribute, DescriptionAttribute("定位模式选择，可选最小二乘法、抗差最小二乘法、kalman滤波、抗差kalman滤波、抗差自适应kalman滤波方法"), CategoryAttribute("定位解算设置")]
        public EPositionType PositionType
        {
            get { return _PositionType; }
            set { _PositionType = value; }
        }
        /// <summary>
        /// 定位解算时使用的卫星钟差模型
        /// </summary>
        [XmlAttribute, DescriptionAttribute("定位解算时使用的卫星钟差模型"), CategoryAttribute("定位解算设置")]
        public ESatClkModelType PPSatclkModel
        {
            get { return _PPSatclkModel; }
            set { _PPSatclkModel = value; }
        }
        /// <summary>
        /// 定位解算时使用的电离层模型
        /// </summary>
        [XmlAttribute, DescriptionAttribute("定位解算时使用的电离层模型"), CategoryAttribute("定位解算设置")]
        public EIonModelType PPIonModel
        {
            get { return _PPIonModel; }
            set { _PPIonModel = value; }
        }
        /// <summary>
        /// 定位解算时使用的多路径模型
        /// </summary>
        [XmlAttribute, DescriptionAttribute("定位解算时使用的多路径模型"), CategoryAttribute("定位解算设置")]
        public EMulModelType PPMulModel
        {
            get { return _PPMulModel; }
            set { _PPMulModel = value; }
        }

        /// <summary>
        /// 定位解算时使用的相位中心偏移模型
        /// </summary>
        [XmlAttribute, DescriptionAttribute("定位解算时使用的相位中心偏移模型"), CategoryAttribute("定位解算设置")]
        public EOffModelType PPOffModel
        {
            get { return _PPOffModel; }
            set { _PPOffModel = value; }
        }
        #endregion 定位解算设置

        #endregion

        #region 初始化

        public void Init()
        {
            Con_FresDic.Clear();
            AllSatsObsDataDic = new List<Dictionary<string, List<ObsReceiverOutput>>>();

            ALLObsSatsDataDic_ConType = new List<Dictionary<EConstellationType, Dictionary<string, List<ObsReceiverOutput>>>>();
            bool IsGenerateObsDataFlag = (Parent.Parent.Parent.Parent.Parent as Scenario).IsGenerateObsData;
            if (IsGenerateObsDataFlag == true)
            {
                #region 频点赋值
                SpaceSegment temp = new SpaceSegment();//获取空间段，使用卫星轨道数据
                temp = (Parent.Parent.Parent.Parent.Parent as Scenario).SegmentColletion[0] as SpaceSegment;

                string[] rectypetemp = RecType.ToString().Split(new string[1] { "_" }, StringSplitOptions.RemoveEmptyEntries);

                for (int i = 0; i < temp.ConstellationList.Count(); i++)
                {
                    int FreNum = 0;
                    foreach (ERecType recType in RecType_Fre.Keys)
                    {
                        if (recType.ToString() == temp.ConstellationList[i].ConstellationFeature.ConstellationType.ToString())
                        {
                            Con_FresDic.Add(temp.ConstellationList[i].ConstellationFeature.ConstellationType, RecType_Fre[recType]);
                            FreNum += RecType_Fre[recType].Count;
                        }
                    }
                    if (FreNum == 0)
                    {
                        MessageBox.Show("请设置接收机频点！");
                        Thread thd = Thread.CurrentThread;
                        BDSimObject.GlobalStatus = ESimStatus.UnInited;
                        this.Parent.Parent.Parent.Parent.Parent.Status = ESimStatus.UnInited;
                        thd.Abort();
                    }
                    if (Con_FresDic.Keys.Count == 0)
                    {
                        MessageBox.Show("接收机频点设置和空间段卫星类型不匹配！");
                        Thread thd = Thread.CurrentThread;
                        BDSimObject.GlobalStatus = ESimStatus.UnInited;
                        this.Parent.Parent.Parent.Parent.Parent.Status = ESimStatus.UnInited;
                        thd.Abort();
                    }
                }
                #endregion 频点赋值
                RecPosInit();
            }
        }

        #endregion

        #region 单步运行

        public void StepRun()
        {
            Scenario temp = (Parent.Parent.Parent.Parent.Parent as Scenario);

            //观测数据实时生成
            bool IsGenerateObsDataFlag = temp.IsGenerateObsData;
            if (IsGenerateObsDataFlag == true)
            {
                RealTimeObsDataGenSim();
            }

            //实时定位
            bool IsPPositioningFlag = temp.IsPPositioning;
            if (IsPPositioningFlag == true)
            {
                RealTimeRecPVT(Con_SingleTimAllSatsObsDic);
            }

            if (_UpDatePPositionResult != null)
            {
                CalculateSatSpaceParam();
                NodePosVel ppositionError = new NodePosVel(BDSimObject.GlobalCurrentTime, FixedPosVelXYZ.X - _Parent.Pos_XYZ.X, FixedPosVelXYZ.Y - _Parent.Pos_XYZ.Y, FixedPosVelXYZ.Z - _Parent.Pos_XYZ.Z, 0, 0, 0);
                _UpDatePPositionResult(ppositionError, FixedPosVelXYZ, BDSimObject.GlobalCurrentTime, SatSpaceParamList, DopResult);
            }

            #region 存储数据

            //存储观测数据
            string directotyname = Parent.Parent.Parent.Parent.directotyname;
            string Obsfilename;//观测数据文件的名称
            string PPfilename;//定位数据文件的名称

            string Obsdirectotyname = directotyname + "\\监测站\\" + "观测数据\\";

            if (!Directory.Exists(Obsdirectotyname))
            {
                Directory.CreateDirectory(Obsdirectotyname);
            }

            Obsfilename = Obsdirectotyname + "Obs-" + Parent.Name + "(实时)" + ".txt";
            string tempdata;

            foreach (var SatObsList in SingleTimAllSatsObs)
            {
                foreach (var SatObs in SatObsList.Value)
                {
                    tempdata = "";
                    tempdata = SatObs.CurTime.year.ToString() + " ";
                    tempdata += SatObs.CurTime.Mon.ToString() + " ";
                    tempdata += SatObs.CurTime.day.ToString() + " ";
                    tempdata += SatObs.CurTime.hour.ToString() + " ";
                    tempdata += SatObs.CurTime.min.ToString() + " ";
                    tempdata += SatObs.CurTime.Sec.ToString("0.00") + " ";
                    tempdata += SatObs.SatID.ToString() + " ";
                    tempdata += SatObs.SatObs.A_Pseudo_writein.ToString() + " ";
                    tempdata += SatObs.SatObs.A_Carri_writein.ToString() + "\n";
                    File.AppendAllText(Obsfilename, tempdata);
                }
            }

            //存储定位数据
            string PPdirectotyname = directotyname + "\\监测站\\" + "定位数据\\";
            if (!Directory.Exists(PPdirectotyname))
            {
                Directory.CreateDirectory(PPdirectotyname);
            }

            PPfilename = PPdirectotyname + "PPositioning-" + Parent.Name + "(实时)" + ".txt";

            tempdata = "";
            tempdata = FixedPosVelXYZ.x.ToString() + " ";
            tempdata += FixedPosVelXYZ.y.ToString() + " ";
            tempdata += FixedPosVelXYZ.z.ToString() + " ";
            tempdata += (FixedPosVelXYZ.x - _Parent.Pos_XYZ.X).ToString() + " ";
            tempdata += (FixedPosVelXYZ.y - _Parent.Pos_XYZ.Y).ToString() + " ";
            tempdata += (FixedPosVelXYZ.z - _Parent.Pos_XYZ.Z).ToString() + "\n";
            File.AppendAllText(PPfilename, tempdata);

            #endregion
        }

        #region 实现定位评估的接口
        [XmlIgnore, Browsable(false)]
        public Action<NodePosVel, NodePosVel, UTCTime, List<SatPredictStatus>, DopDLL.DopOutput> UpDatePPositionResult
        {
            get
            {
                return _UpDatePPositionResult;
            }
            set
            {
                _UpDatePPositionResult = value;
            }
        }
        #endregion

        #endregion

        #region 单步运行函数

        /// <summary>
        /// 观测数据实时生成
        /// </summary>
        public void RealTimeObsDataGenSim()
        {
            SingleTimAllSatsObs.Clear();
            Con_SingleTimAllSatsObsDic.Clear();

            UTCTime CurTime;
            double nowTime = (BDSimObject.GlobalCurrentTime.Jd - BDSimObject.GlobalStartTime.Jd) * 86400.0;//当前系统运行时刻
            CurTime = BDSimObject.GlobalCurrentTime;//更新观测数据计算模型的时间信息

            SpaceSegment temp = new SpaceSegment();
            temp = (Parent.Parent.Parent.Parent.Parent as Scenario).SegmentColletion[0] as SpaceSegment;

            Dictionary<string, List<ObsReceiverOutput>> curObs = new Dictionary<string, List<ObsReceiverOutput>>();
            for (int i = 0; i < temp.ConstellationList.Count(); i++)
            {
                foreach (var ConType_Fre in Con_FresDic)
                {
                    if (ConType_Fre.Key == temp.ConstellationList[i].ConstellationFeature.ConstellationType)
                    {
                        List<List<NodePosVel>> SatsPVLst = new List<List<NodePosVel>>();//存储当前时刻该星座所有卫星10个轨道值
                        List<double> obsSatsClk = new List<double>();// 获取单个时刻该星座所有卫星钟差 
                        List<string> satNameList = new List<string>();
                        List<double[]> satPhaseOffList = new List<double[]>();  //卫星相位中心偏移

                        double orbPreDtep = temp.ConstellationList[i].SatelliteCollection[0].Orbit.IntegrationParam.StepSize;

                        int timeId = (int)(Math.Floor((nowTime + 0.0001) / orbPreDtep));

                        foreach (var Sat in temp.ConstellationList[i].SatelliteCollection)
                        {
                            List<NodePosVel> satPVLst = new List<NodePosVel>();
                            int satPVListNum = Sat.OrbitPVList.Count();

                            if (timeId < 5)
                            {
                                timeId = 4;
                            }
                            if (satPVListNum - timeId < 5)
                            {
                                timeId = satPVListNum - 5;
                            }

                            for (int k = 0; k < 10; k++)
                            {
                                satPVLst.Add(Sat.OrbitPVList[timeId - 4 + k].SatPV_ECI);
                            }

                            SatsPVLst.Add(satPVLst);

                            obsSatsClk.Add(Sat.Clock.Clk_Err);   //获取当前时刻每颗卫星钟差
                            satNameList.Add(Sat.Name);
                            satPhaseOffList.Add(Sat.PhaseOff);
                        }

                        /* 计算单个时刻所有可见星观测值 */

                        double[] DeltRanThH = new double[2];
                        DeltRanThH[0] = PseudoRanThH;
                        DeltRanThH[1] = CarrRanThH;

                        Dictionary<string, List<ObsReceiverOutput>> ObsSatsDataDic = new Dictionary<string, List<ObsReceiverOutput>>();  //单星座单个时刻所有可见星观测值
                        SingleTimConSatsObsCal(SatsPVLst, obsSatsClk, satNameList, satPhaseOffList, RecPVECF, CurTime, DeltRanThH, Elelim, ObsErrFlag.ConvertToStruct(), ConType_Fre.Value, out ObsSatsDataDic);

                        Con_SingleTimAllSatsObsDic.Add(ConType_Fre.Key, new Dictionary<string, List<ObsReceiverOutput>>());
                        Con_SingleTimAllSatsObsDic[ConType_Fre.Key] = ObsSatsDataDic;

                        foreach (var item in ObsSatsDataDic)
                        {
                            if (curObs.ContainsKey(item.Key))
                            {
                                curObs[item.Key] = item.Value;
                            }
                            else
                            {
                                curObs.Add(item.Key, new List<ObsReceiverOutput>());
                                curObs[item.Key] = item.Value;
                            }
                        }
                    }
                }
            }
            if (this.Parent.Parent.Parent.Parent.Parent.ObsSaveFlag == true)
            {
              //  AllSatsObsDataDic.Add(curObs);
                ALLObsSatsDataDic_ConType.Add(Con_SingleTimAllSatsObsDic);
            }
        }

        #endregion

        #region 方法

        #region 观测数据生成

        #region 初始化中的方法
        /// <summary>
        /// 根据载体位置、接收机安装位置计算接收机的位置
        /// </summary>
        private void RecPosInit()
        {
            ENU_PosVel recenu = new ENU_PosVel();
            recenu.epoch = GlobalCurrentTime;
            recenu.E = DeltaPos.X;
            recenu.N = DeltaPos.Y;
            recenu.U = DeltaPos.Z;
            recenu.v_E = 0.0;
            recenu.v_N = 0.0;
            recenu.v_U = 0.0;

            NodePosVel stationposvel = new NodePosVel();
            stationposvel.x = Parent.Pos_XYZ.X;
            stationposvel.y = Parent.Pos_XYZ.Y;
            stationposvel.z = Parent.Pos_XYZ.Z;

            TimeSpaceDll.ENU2ECF(stationposvel, recenu, ECFtype.type_CGCS2000, out RecPVECF);

        }

        /// 仿真时间段与所有可见卫星的观测值
        //public void MonitorObservationGen(out List<Dictionary<string, List<ObsReceiverOutput>>> AllSatsObsDataDic)
        //{
        //    List<Dictionary<string, List<ObsReceiverOutput>>> TempAllSatsObsDataDic = new List<Dictionary<string, List<ObsReceiverOutput>>>();

        //    /* 获取空间段所有卫星信息 */
        //    SpaceSegment temp = new SpaceSegment();
        //    temp = (Parent.Parent.Parent.Parent.Parent as Scenario).SegmentColletion[0] as SpaceSegment;

        //    UTCTime Curtime = BDSimObject.GlobalStartTime;// 把开始时间赋值给临时时间     

        //    /* 每30秒计算一次 */
        //    for (int SimClks = 0; BDSimObject.GlobalEndTime.JD > Curtime.JD; SimClks++)
        //    {
        //        /*计算当前时间，按30秒累加*/
        //        double SimStep = BDSimObject.GlobalStepSize;
        //        double nowTime = SimClks * SimStep;//生成固定步长的观测数据
        //        Curtime.IntJD = BDSimObject.GlobalStartTime.IntJD + Math.Floor(nowTime / 86400.0);
        //        Curtime.DouJD = BDSimObject.GlobalStartTime.DouJD + nowTime / 86400.0 - Math.Floor(nowTime / 86400.0);
        //        Curtime.JD = Curtime.IntJD + Curtime.DouJD;
        //        TimeSpaceDll.CAL2UTC(out Curtime, 2);

        //        Dictionary<string, List<ObsReceiverOutput>> tempobs = new Dictionary<string, List<ObsReceiverOutput>>();
        //        for (int i = 0; i < temp.ConstellationList.Count(); i++)
        //        {
        //            foreach (var frequency_ConType in Con_FresDic)
        //            {
        //                if (frequency_ConType.Key == temp.ConstellationList[i].ConstellationFeature.ConstellationType)
        //                {
        //                    List<List<NodePosVel>> SatsPVLst = new List<List<NodePosVel>>();//存储当前时刻的所有卫星10个轨道值
        //                    List<double> obsSatsClk = new List<double>();
        //                    List<string> satNameList = new List<string>();
        //                    List<double[]> satPhaseOffList = new List<double[]>();  //卫星相位中心偏移
        //                    /*获取10个卫星轨道值  */
        //                    double orbPreDtep = temp.ConstellationList[i].SatelliteCollection[0].Orbit.IntegrationParam.StepSize;

        //                    int timeId = (int)(Math.Floor((nowTime + 0.0001) / orbPreDtep));

        //                    foreach (var Sat in temp.ConstellationList[i].SatelliteCollection)
        //                    {
        //                        List<NodePosVel> satPVLst = new List<NodePosVel>();
        //                        int satPVListNum = Sat.OrbitPVList.Count();

        //                        if (timeId < 5)
        //                        {
        //                            for (int k = 0; k < 10; k++)
        //                            {
        //                                satPVLst.Add(Sat.OrbitPVList[k].SatPV_ECI);
        //                            }
        //                        }
        //                        else if (satPVListNum - timeId < 6)
        //                        {
        //                            for (int k = 0; k < 10; k++)
        //                            {
        //                                satPVLst.Add(Sat.OrbitPVList[satPVListNum - 10 + k].SatPV_ECI);
        //                            }
        //                        }
        //                        else
        //                        {
        //                            for (int k = 0; k < 10; k++)
        //                            {
        //                                satPVLst.Add(Sat.OrbitPVList[timeId - 4 + k].SatPV_ECI);
        //                            }
        //                        }

        //                        SatsPVLst.Add(satPVLst);

        //                        obsSatsClk.Add(Sat.RealTimeClkErr(Curtime));
        //                        satNameList.Add(Sat.Name);
        //                        satPhaseOffList.Add(Sat.PhaseOff);
        //                    }

        //                    /* 计算单个时刻所有可见星观测值 */

        //                    double[] DeltRanThH = new double[2];
        //                    DeltRanThH[0] = PseudoRanThH;
        //                    DeltRanThH[1] = CarrRanThH;

        //                    Dictionary<string, List<ObsReceiverOutput>> ObsSatsDataDic = new Dictionary<string, List<ObsReceiverOutput>>();  //单星座单个时刻所有可见星观测值
        //                    SingleTimConSatsObsCal(SatsPVLst, obsSatsClk, satNameList, satPhaseOffList, RecPVECF, Curtime, DeltRanThH, Elelim, ObsErrFlag.ConvertToStruct(), frequency_ConType.Value, out ObsSatsDataDic);
        //                    // tempobs
        //                    foreach (var item in ObsSatsDataDic)
        //                    {
        //                        if (tempobs.ContainsKey(item.Key))
        //                        {
        //                            tempobs[item.Key] = item.Value;
        //                        }
        //                        else
        //                        {
        //                            tempobs.Add(item.Key, new List<ObsReceiverOutput>());
        //                            tempobs[item.Key] = item.Value;
        //                        }
        //                    }
        //                }
        //            }
        //        }
        //        TempAllSatsObsDataDic.Add(tempobs);
        //    }
        //    AllSatsObsDataDic = TempAllSatsObsDataDic;
        //}

        #endregion

        /// 单个时刻所有可见卫星观测值
        public void SingleTimConSatsObsCal(List<List<NodePosVel>> AllSatPVLst, List<double> obsSatsClkLst, List<string> satNameList,
                                           List<double[]> satPhaseOffList, NodePosVel ReceiverECFPos, UTCTime CurTime, double[] DeltRanThH, double Elelim, ObsErrFlag ErrFlag,
                                           List<EFrePoint> FreLst, out Dictionary<string, List<ObsReceiverOutput>> SingleTimConAllSatsObs)
        {
            Dictionary<string, List<ObsReceiverOutput>> TempSingleTimConAllSatsObs = new Dictionary<string, List<ObsReceiverOutput>>(); ///单个时刻单个星座所有可见卫星观测值

            ObsReceiverInPut pObsReceiverInPut = new ObsReceiverInPut();

            pObsReceiverInPut.SatID = 1;

            int SatCount = 0;

            //按固定步长生成仿真时段内的观测数据（所有卫星）
            foreach (var item in AllSatPVLst)
            {
                List<NodePosVel> obsSatsPV = new List<NodePosVel>();

                obsSatsPV = item.ToList();

                pObsReceiverInPut.CurTime = CurTime;
                pObsReceiverInPut.SendPosFlag = 0;
                pObsReceiverInPut.StaID = 0;

                NodePosVel ReceiverPosECI = new NodePosVel();
                ReceiverECFPos.epoch = CurTime;
                TimeSpaceDll.ECF2ECI(ReceiverECFPos, 0, 0, out ReceiverPosECI);
                pObsReceiverInPut.ReceiverPos = ReceiverPosECI;

                pObsReceiverInPut.SendPos = new NodePosVel[10];
                for (int j = 0; j < 10; j++)//卫星位置赋值
                {
                    pObsReceiverInPut.SendPos[j] = obsSatsPV[j];
                }
                // pObsReceiverInPut.DeltRanThH = new double[2];
                //pObsReceiverInPut.DeltRanThH[0] = DeltRanThH[0];//伪距噪声量级（界面输入）
                //pObsReceiverInPut.DeltRanThH[1] = DeltRanThH[1];//载波相位噪声量级（界面输入）

                double calelelim;
                double Azi;
                double ErrValue = 0;

                /// <summary>
                /// 单个时刻所有频点可见星观测值
                /// </summary>
                List<ObsReceiverOutput> RecSingleFreObsOutput = new List<ObsReceiverOutput>();

                NodePosVel SatOrbECF = new NodePosVel();
                TimeSpaceDll.ECI2ECF(pObsReceiverInPut.SendPos[4], 0, 0, out SatOrbECF);

                if (1 == CAccessCalDLL.StationAccess(ReceiverECFPos, SatOrbECF, ECFtype.type_CGCS2000, Elelim, out calelelim, out Azi))
                {
                    //观测误差计算
                    #region 误差计算
                    if (ErrFlag.IsSatClk)//卫星钟差
                    {
                        ErrValue = -obsSatsClkLst[SatCount] * 2.99792458E8;
                    }
                    else
                    {
                        ErrValue = 0;
                    }


                    if (ErrFlag.IsStaClk)//地面站钟差
                    {
                        ErrValue = Parent.RealTimeClkErr(CurTime) * 2.99792458E8;
                    }
                    else
                    {
                        ErrValue += 0;
                    }

                    if (ErrFlag.IsItro)//对流层误差
                    {
                        CalTro_Input troinput = new CalTro_Input();
                        troinput.SatECFPos = new double[3];
                        troinput.UsePos = new double[3];

                        Parent.GetMeteorological(CurTime);
                        troinput.Tro = Parent.StationMeteParam;

                        troinput.SatECFPos[0] = SatOrbECF.x;
                        troinput.SatECFPos[1] = SatOrbECF.y;
                        troinput.SatECFPos[2] = SatOrbECF.z;
                        troinput.UsePos[0] = ReceiverECFPos.x;
                        troinput.UsePos[1] = ReceiverECFPos.y;
                        troinput.UsePos[2] = ReceiverECFPos.z;

                        double DeltTro = 0;
                        int Itro = 1;
                        switch (ObsTroModel)
                        {
                            case ETroModelType.Hopfield:
                                Itro = 1;
                                break;
                            case ETroModelType.ImprovedHopfield:
                                Itro = 2;
                                break;
                            case ETroModelType.Saastamoinen:
                                Itro = 3;
                                break;
                        }
                        TropDLL.CalTro_output(troinput, Itro, out DeltTro);

                        ErrValue += DeltTro;
                    }
                    else
                    {
                        ErrValue += 0;
                    }

                    if (ErrFlag.IsImul)
                    {
                        double multiDelay = 0;
                        double[] UseECFPos = new double[3];
                        double[] SatECFPos = new double[3];
                        double MaxValue = 5;  //随机误差的最大值
                        double Ele = 0;
                        double azi = 0;

                        SatECFPos[0] = SatOrbECF.x;
                        SatECFPos[1] = SatOrbECF.y;
                        SatECFPos[2] = SatOrbECF.z;

                        UseECFPos[0] = ReceiverECFPos.x;
                        UseECFPos[1] = ReceiverECFPos.y;
                        UseECFPos[2] = ReceiverECFPos.z;

                        CalEleAziDLL.Cal_EleAzi(UseECFPos, SatECFPos, ref Ele, ref azi);
                        MulPathDelayDLL.CalMultiPath(MaxValue, Ele, ref multiDelay);

                        ErrValue += multiDelay;
                    }
                    else
                    {
                        ErrValue += 0;
                    }

                    if (ErrFlag.IsIoff)
                    {
                        double DeltOff = 0;
                        caloff_input pCalOff_Input;

                        pCalOff_Input.CurTime = CurTime;

                        pCalOff_Input.SatECFPos = new double[3];
                        pCalOff_Input.SatECFPos[0] = SatOrbECF.x;
                        pCalOff_Input.SatECFPos[1] = SatOrbECF.y;
                        pCalOff_Input.SatECFPos[2] = SatOrbECF.z;

                        pCalOff_Input.UseECFPos = new double[3];
                        pCalOff_Input.UseECFPos[0] = ReceiverECFPos.x;
                        pCalOff_Input.UseECFPos[1] = ReceiverECFPos.y;
                        pCalOff_Input.UseECFPos[2] = ReceiverECFPos.z;

                        pCalOff_Input.S_Off = new double[3];
                        pCalOff_Input.S_Off = satPhaseOffList[SatCount];

                        pCalOff_Input.U_Off = new double[3];
                        pCalOff_Input.U_Off[0] = U_Off.E;
                        pCalOff_Input.U_Off[1] = U_Off.N;
                        pCalOff_Input.U_Off[2] = U_Off.U;

                        COffSetDLL.CalPhaseOffset_output(pCalOff_Input, 1, out DeltOff);
                    }
                    else
                    {
                        ErrValue += 0;

                    }

                    if (ErrFlag.IsIrel)
                    {
                        double DeltRel = 0.0;
                        RelDLL.CalRel_output(pObsReceiverInPut.SendPos[4], 1, out DeltRel);
                        ErrValue += DeltRel;
                    }
                    else
                    {
                        ErrValue += 0;
                    }

                    #endregion 误差计算

                    ObsReceiverOutput output = new ObsReceiverOutput();
                    pObsReceiverInPut.ObsErr = new double[2];
                    foreach (var Fre in FreLst)
                    {
                        // pObsReceiverInPut.Freq = Fre;

                        FreFlagValue freflag = new FreFlagValue();
                        pObsReceiverInPut.Freq = freflag.FreDic[Fre];
                        switch (Fre)
                        {
                            case EFrePoint.GLONASS_L1:
                                pObsReceiverInPut.Freq += freflag.DicGloFrq[pObsReceiverInPut.SatID] * 0.5625;//9/16
                                break;
                            case EFrePoint.GLONASS_L2:
                                pObsReceiverInPut.Freq += freflag.DicGloFrq[pObsReceiverInPut.SatID] * 0.4375;//7 / 16
                                break;
                            default:
                                break;
                        }

                        if (ErrFlag.IsIion)//电离层误差计算
                        {
                            CalIon_Input ioninput;
                            ioninput.Time = CurTime;
                            ioninput.SatECFPos = new double[3];
                            ioninput.SatECFPos[0] = SatOrbECF.x;
                            ioninput.SatECFPos[1] = SatOrbECF.y;
                            ioninput.SatECFPos[2] = SatOrbECF.z;
                            ioninput.UsePos = new double[3];
                            ioninput.UsePos[0] = ReceiverECFPos.x;
                            ioninput.UsePos[1] = ReceiverECFPos.y;
                            ioninput.UsePos[2] = ReceiverECFPos.z;

                            CalIon_Output ionoutput;
                            int IIon = 1;
                            switch (ObsIonModel)
                            {
                                case IonSimModelType.球谐模型:
                                    IIon = 1;
                                    break;
                                case IonSimModelType.全球格网插值模型:
                                    IIon = 2;
                                    break;
                            }
                            IonTEC.CalIon_output(ioninput, IIon, out ionoutput);

                            double DeltIon = 0;
                            IonMapDLL.Ion_VTEC2DST(ionoutput.VTEC, pObsReceiverInPut.Freq, ionoutput.Zenith, 1, out DeltIon);

                            pObsReceiverInPut.ObsErr[0] = ErrValue + DeltIon;
                            pObsReceiverInPut.ObsErr[1] = ErrValue - DeltIon;
                        }
                        else
                        {

                            pObsReceiverInPut.ObsErr[0] = ErrValue + 0;
                            pObsReceiverInPut.ObsErr[1] = ErrValue - 0;
                        }

                        int aa = CObsDataGenDLL.ObsRecvInit(pObsReceiverInPut, out output);

                        pCalRan_Input.DeltRanThH = PseudoRanThH;
                        double PseudoRan = NoiseServiceDLL.CalRan_output(ref pCalRan_Input, 1);

                        pCalRan_Input.DeltRanThH = CarrRanThH;
                        double CarrRan = NoiseServiceDLL.CalRan_output(ref pCalRan_Input, 1);
                        output.SatObs.A_Pseudo_writein += PseudoRan;
                        output.SatObs.A_Carri_writein += CarrRan;

                        RecSingleFreObsOutput.Add(output);
                    }

                    if (TempSingleTimConAllSatsObs.ContainsKey(satNameList[SatCount]))
                    {
                        TempSingleTimConAllSatsObs[satNameList[SatCount]] = RecSingleFreObsOutput;
                    }
                    else
                    {
                        TempSingleTimConAllSatsObs.Add(satNameList[SatCount], new List<ObsReceiverOutput>());
                        TempSingleTimConAllSatsObs[satNameList[SatCount]] = RecSingleFreObsOutput;
                    }
                }
                pObsReceiverInPut.SatID++;
                SatCount++;
            }
            SingleTimConAllSatsObs = TempSingleTimConAllSatsObs;
        }

        #endregion

        #region 监测站定位实现

        /// <summary>
        /// 实时PVT解算
        /// </summary>
        /// <param name="SingleTimConAllSatsObsDataDic">当前时刻分星座存储的可见星观测数据</param></param>
        /// <param name="FixedPosVelXYZ">定位结果</param>
        /// <param name="DopResult">定位DOP值</param>
        public void RealTimeRecPVT(Dictionary<EConstellationType, Dictionary<string, List<ObsReceiverOutput>>> SingleTimConAllSatsObsDataDic)
        {
            GroundSegment temp = new GroundSegment();
            temp = (Parent.Parent.Parent.Parent.Parent as Scenario).SegmentColletion[2] as GroundSegment;

            if ((temp.SubGroundSegmentList.Count <= 0) & (0 == SubGroundSegmentNumFlag))
            {
                MessageBox.Show("没有主控站，不能完成定位！");
                SubGroundSegmentNumFlag = 1;
                return;
            }

            List<EConstellationType> ObsSatsDataDicKey = Con_SingleTimAllSatsObsDic.Keys.ToList();
            RecFixedData = new Dictionary<EConstellationType, PPositionning_Output>();//分星座实时存储的当前时刻的定位结果
            for (int i = 0; i < Con_SingleTimAllSatsObsDic.Count(); i++)//根据观测数据的星座类型进行循环
            {
                foreach (SubGroundSegment subgroundtemp in temp.SubGroundSegmentList)//搜索地面段的类型，判断是否有对应星座类型的星历数据
                {
                    if (subgroundtemp.Type == ObsSatsDataDicKey[i])//地面段类型和星座类型匹配
                    {

                        foreach (StationCollection stacollectiontemp in subgroundtemp.GroundList)//遍历地面段中的站类型，看是否有主控站
                        {
                            if (EStationType.MasterStation == stacollectiontemp.Type)//地面段中有主控站
                            {
                                if ((stacollectiontemp.StationList.Count() <= 0) & (0 == StaNumFlag))
                                {
                                    MessageBox.Show("没有星历数据(请添加主控站或打开星历拟合开关)！");
                                    StaNumFlag = 1;
                                }

                                MasterStaFlag = 1;//标记场景中有主控站，且个数不少于1

                                if (stacollectiontemp.StationList.Count() > 0)
                                {
                                    MasterStation masterstation = (MasterStation)stacollectiontemp.StationList[0];

                                    PPositionning_Input pp_input = new PPositionning_Input();
                                    PPositionning_Param pp_param = new PPositionning_Param();
                                    PPositionning_Output pp_output = new PPositionning_Output();

                                    if ((0 == masterstation.SatEph16Dic.Count()) & (0 == EphNumFlag))
                                    {
                                        MessageBox.Show("没有星历数据，不能完成定位功能！");
                                        EphNumFlag = 1;
                                    }

                                    if (masterstation.SatEph16Dic.Count() > 4)
                                    {
                                        pp_input.CurTime = BDSimObject.GlobalCurrentTime;
                                        pp_input.ReceiverID = Id;
                                        pp_input.ReceiverPos = new double[3] { RecPVECF.x, RecPVECF.y, RecPVECF.z };

                                        pp_input.ObsTotalSatnum = Con_SingleTimAllSatsObsDic[ObsSatsDataDicKey[i]].Count();//获取当前星座中可见星个数
                                        if (pp_input.ObsTotalSatnum > 0)
                                        {
                                            List<string> satNameList = Con_SingleTimAllSatsObsDic[ObsSatsDataDicKey[i]].Keys.ToList();//获取当前星座中可见星名称

                                            double nowTime = (BDSimObject.GlobalCurrentTime.Jd - BDSimObject.GlobalStartTime.Jd) * 86400.0;//运行时间长度
                                            int NavMsgId = (int)(nowTime / 3600.0);//因1小时生成一组星历，用于判断取第几组星历数据
                                            if (NavMsgId == masterstation.SatEph16Dic[satNameList[0]].Count())
                                            {
                                                NavMsgId--;
                                            }

                                            pp_input.ObsSatInfo = new SatInfo[20];
                                            if (pp_input.ObsTotalSatnum >= 4)
                                            {
                                                for (int j = 0; j < pp_input.ObsTotalSatnum; j++)
                                                {
                                                    pp_input.ObsSatInfo[j].SatID = Con_SingleTimAllSatsObsDic[ObsSatsDataDicKey[i]][satNameList[j]][0].SatID;//卫星编号

                                                    //观测数据赋值
                                                    pp_input.ObsSatInfo[j].SatObs.SatID = Con_SingleTimAllSatsObsDic[ObsSatsDataDicKey[i]][satNameList[j]][0].SatID;//卫星编号
                                                    pp_input.ObsSatInfo[j].SatObs.Code_Pseudo = new double[6];
                                                    pp_input.ObsSatInfo[j].SatObs.Carrier_Phase = new double[6];

                                                    for (int k = 0; k < Con_SingleTimAllSatsObsDic[ObsSatsDataDicKey[i]][satNameList[j]].Count(); k++)//有多少个频点的观测数据赋多少个值
                                                    {
                                                        pp_input.ObsSatInfo[j].SatObs.Code_Pseudo[k] = Con_SingleTimAllSatsObsDic[ObsSatsDataDicKey[i]][satNameList[j]][k].SatObs.A_Pseudo_writein;
                                                        pp_input.ObsSatInfo[j].SatObs.Carrier_Phase[k] = Con_SingleTimAllSatsObsDic[ObsSatsDataDicKey[i]][satNameList[j]][k].SatObs.A_Carri_writein;
                                                    }

                                                    //星历数据赋值
                                                    pp_input.ObsSatInfo[j].SingleSatNavMsg.SatID = Con_SingleTimAllSatsObsDic[ObsSatsDataDicKey[i]][satNameList[j]][0].SatID;//卫星编号
                                                    pp_input.ObsSatInfo[j].SingleSatNavMsg.EphemerisSixteen = masterstation.SatEph16Dic[satNameList[j]][NavMsgId];
                                                    pp_input.ObsSatInfo[j].SingleSatNavMsg.ClkErrMsg = masterstation.ClockErrDic[satNameList[j]][NavMsgId];
                                                    pp_input.ObsSatInfo[j].SingleSatNavMsg.IonEightParam = masterstation.IonoFitOutputMsgList[0].IonoFitOutput.EightIonoData;
                                                }

                                                #region 误差控制参数赋值
                                                if (ObsErrFlag.IsIion)
                                                {
                                                    pp_param.Iion = 1;
                                                    switch (PPIonModel)
                                                    {
                                                        case EIonModelType.EightParam:
                                                            pp_param.m_nMode = 1;
                                                            break;
                                                        //case EIonModelType.FourteenParam:
                                                        //    pp_param.m_nMode = 1;
                                                        //    break;
                                                        //case EIonModelType.Grid:
                                                        //    pp_param.m_nMode = 1;
                                                        //    break;
                                                        case EIonModelType.DoubleFre:
                                                            pp_param.m_nMode = 2;
                                                            break;
                                                        default:
                                                            break;
                                                    }
                                                }
                                                else
                                                {
                                                    pp_param.Iion = 0;
                                                }
                                                if (ObsErrFlag.IsItro)
                                                {
                                                    pp_param.Itro = 1;
                                                }
                                                else
                                                {
                                                    pp_param.Itro = 0;
                                                }
                                                if (ObsErrFlag.IsIrel)
                                                {
                                                    pp_param.Irel = 1;
                                                }
                                                else
                                                {
                                                    pp_param.Irel = 0;
                                                }
                                                if (ObsErrFlag.IsSatClk)
                                                {
                                                    pp_param.Iclo = 1;
                                                }
                                                else
                                                {
                                                    pp_param.Iclo = 0;
                                                }
                                                #endregion 误差控制参数赋值


                                                pp_param.Freq = new double[3];
                                                for (int k = 0; k < Con_FresDic[ObsSatsDataDicKey[i]].Count(); k++)//定位时输入的接收机频率不大于3
                                                {
                                                    FreFlagValue freflag = new FreFlagValue();
                                                    pp_param.Freq[k] = freflag.FreDic[Con_FresDic[ObsSatsDataDicKey[i]][k]];
                                                }
                                                pp_input.SysType = ObsSatsDataDicKey[i];
                                                PPositionDLL.PPositioning(pp_input, pp_param, out pp_output, PositionType);
                                                RecFixedData.Add(ObsSatsDataDicKey[i], pp_output);

                                                SatNumFlag = 0;
                                            }

                                            if ((0 == SatNumFlag) & (pp_input.ObsTotalSatnum < 4))
                                            {
                                                MessageBox.Show("可见星少于4颗，不能正确定位！");
                                                DlgReportSimInfo(SimInfo.NewSimInfo(this.Name, "可见星少于4颗，不能正确定位", OutputType.消息, GlobalCurrentTime));
                                                SatNumFlag = 1;
                                            }

                                        }
                                        if ((0 == pp_input.ObsTotalSatnum) & (SatNumFlag != 2))
                                        {
                                            DlgReportSimInfo(SimInfo.NewSimInfo(this.Name, "没有可见卫星，不能正确定位", OutputType.消息, GlobalCurrentTime));
                                            SatNumFlag = 2;
                                        }

                                    }
                                }
                            }


                        }

                        if (0 == MasterStaFlag)
                        {
                            MessageBox.Show("没有星历数据，请添加主控站！");
                            MasterStaFlag = 1;
                        }


                    }
                }
            }

            if (true)//根据判断确定使用哪个系统的定位结果
            {
                if (0 == RecFixedData.Count)//如果可见卫星个数少于4，则定位结果默认为0
                {
                    PPositionning_Output pp_output1 = new PPositionning_Output();
                    pp_output1.X = new double[3];
                    pp_output1.X[0] = 0;
                    pp_output1.X[1] = 0;
                    pp_output1.X[2] = 0;

                    RecFixedData.Add(ObsSatsDataDicKey[0], pp_output1);
                }
                NodePosVel tempp = new NodePosVel();
                tempp.epoch = BDSimObject.GlobalCurrentTime;
                tempp.x = RecFixedData[ObsSatsDataDicKey[0]].X[0];
                tempp.y = RecFixedData[ObsSatsDataDicKey[0]].X[1];
                tempp.z = RecFixedData[ObsSatsDataDicKey[0]].X[2];
                FixedPosVelXYZ = tempp;
                DopResult = RecFixedData[ObsSatsDataDicKey[0]].DOP;
            }

            #region 不考虑多系统
            //GroundSegment temp = new GroundSegment(); 
            //temp = (Parent.Parent.Parent.Parent.Parent as Scenario).SegmentColletion[2] as GroundSegment;
            //ObservableCollection<StationBase> MasterStationList = new ObservableCollection<StationBase>();  //BD地面段主控站集

            //foreach (var subg in temp.SubGroundSegmentList)
            //{
            //    if (EConstellationType.BD == subg.Type)
            //    {
            //        SubGroundSegment bdGroundSegment = subg;
            //        foreach (StationCollection BDGLst in bdGroundSegment.GroundList)
            //        {
            //            if (EStationType.MasterStation == BDGLst.Type)
            //            {
            //                MasterStationList = BDGLst.StationList;
            //            }
            //        }
            //    }
            //}

            //NodePosVel tempFixedPosVelXYZ = new NodePosVel();
            //DopDLL.DopOutput tempDopResult = new DopDLL.DopOutput();

            //if (MasterStationList.Count() < 0)
            //{
            //    MessageBox.Show("没有星历数据（请添加主控站或打开星历拟合开关）！");
            //}

            //if (MasterStationList.Count > 0)
            //{
            //    MasterStation masterstation = new MasterStation();
            //    masterstation = (MasterStation)MasterStationList[0];

            //    PPositionning_Input PP_input = new PPositionning_Input();
            //    PPositionning_Param PP_param = new PPositionning_Param();
            //    PPositionning_Output PP_output = new PPositionning_Output();
            //    if (masterstation.SatEph16Dic.Count() > 4)
            //    {
            //        PP_input.CurTime = BDSimObject.GlobalCurrentTime;
            //        PP_input.ReceiverID = _Parent.Id;
            //        PP_input.ReceiverPos = new double[3];
            //        PP_input.ReceiverPos[0] = _Parent.Pos_XYZ.X;
            //        PP_input.ReceiverPos[1] = _Parent.Pos_XYZ.Y;
            //        PP_input.ReceiverPos[2] = _Parent.Pos_XYZ.Z;

            //        PP_input.ObsTotalSatnum = ObsSatsDataDic.Count();//获取字典中的可见星的个数
            //        List<string> satNameList = ObsSatsDataDic.Keys.ToList();//获取观测数据字典中的所有Key
            //        PP_input.ObsSatInfo = new SatInfo[20];

            //        double nowTime = (BDSimObject.GlobalCurrentTime.Jd - BDSimObject.GlobalStartTime.Jd) * 86400.0;//生成固定步长的观测数据
            //        int NavMsgId = (int)(nowTime / 3600.0);
            //        if (NavMsgId == masterstation.SatEph16Dic[satNameList[0]].Count())
            //        {
            //            NavMsgId--;
            //        }
            //        for (int i = 0; i < PP_input.ObsTotalSatnum; i++)
            //        {
            //            PP_input.ObsSatInfo[i].SatID = ObsSatsDataDic[satNameList[i]][0].SatID;//从DIC中获取相应GUID的卫星编号

            //            //观测数据赋值
            //            PP_input.ObsSatInfo[i].SatObs.SatID = ObsSatsDataDic[satNameList[i]][0].SatID;
            //            PP_input.ObsSatInfo[i].SatObs.Code_Pseudo = new double[6];
            //            PP_input.ObsSatInfo[i].SatObs.Carrier_Phase = new double[6];
            //            for (int j = 0; j < ObsSatsDataDic[satNameList[i]].Count(); j++)//有多少个频点赋多少个值
            //            {
            //                PP_input.ObsSatInfo[i].SatObs.Code_Pseudo[j] = ObsSatsDataDic[satNameList[i]][j].SatObs.A_Pseudo_writein;
            //                PP_input.ObsSatInfo[i].SatObs.Carrier_Phase[j] = ObsSatsDataDic[satNameList[i]][j].SatObs.A_Carri_writein;
            //            }

            //            //星历数据赋值

            //            PP_input.ObsSatInfo[i].SingleSatNavMsg.SatID = ObsSatsDataDic[satNameList[i]][0].SatID;

            //            PP_input.ObsSatInfo[i].SingleSatNavMsg.EphemerisSixteen = masterstation.SatEph16Dic[satNameList[i]][NavMsgId];
            //            PP_input.ObsSatInfo[i].SingleSatNavMsg.ClkErrMsg = masterstation.ClockErrDic[satNameList[i]][NavMsgId];
            //            //PP_input.ObsSatInfo[i].SingleSatNavMsg.IonEightParam = masterstation.CNavMsgFit.IonoFitOutputMsgList[].IonoFitOutput.EightIonoData;

            //            //控制参数赋值
            //            //PP_param.Iion = ObsErrCtrlFlag.IsIion;
            //            //PP_param.Itro = ObsErrCtrlFlag.IsItro;
            //            //PP_param.Irel = ObsErrCtrlFlag.IsIrel;
            //            //PP_param.Iclo = ObsErrCtrlFlag.IsSatClk;
            //            #region 误差控制参数赋值
            //            if (ObsErrFlag.IsIion)
            //            {
            //                PP_param.Iion = 1;
            //                PP_param.m_nMode = 2;
            //            }
            //            else
            //            {
            //                PP_param.Iion = 0;
            //            }
            //            if (ObsErrFlag.IsItro)
            //            {
            //                PP_param.Itro = 1;
            //            }
            //            else
            //            {
            //                PP_param.Itro = 0;
            //            }
            //            if (ObsErrFlag.IsIrel)
            //            {
            //                PP_param.Irel = 1;
            //            }
            //            else
            //            {
            //                PP_param.Irel = 0;
            //            }
            //            if (ObsErrFlag.IsSatClk)
            //            {
            //                PP_param.Iclo = 1;
            //            }
            //            else
            //            {
            //                PP_param.Iclo = 0;
            //            }
            //            #endregion 误差控制参数赋值

            //            int FreNum = FrequencyList.Count();
            //            PP_param.Freq = new double[FreNum];
            //            for (int ii = 0; ii < FreNum; ii++)
            //            {
            //                PP_param.Freq[ii] = FrequencyList[ii];

            //            }

            //            //PP_param.m_nMode = 1;
            //        }

            //        PPositionDLL.PPositioning(PP_input, PP_param, out PP_output, PositionType);

            //        NodePosVel tempp = new NodePosVel();
            //        tempp.epoch = BDSimObject.GlobalCurrentTime;
            //        tempp.x = PP_output.X[0];
            //        tempp.y = PP_output.X[1];
            //        tempp.z = PP_output.X[2];
            //        FixedPosVelXYZ = tempp;
            //        DopResult = PP_output.DOP;
            //    }
            //}
            #endregion
        }

        #endregion

        #region 计算星空参数方法
        /// <summary>
        /// 计算星空参数方法
        /// </summary>
        public void CalculateSatSpaceParam()
        {
            SatSpaceParamList.Clear();
            foreach (var satellite in (Parent.Parent.Parent.Parent.Parent.SegmentColletion[0] as SpaceSegment).AllSatellite)
            {
                double Ele = 0; //高度角
                double Azi = 0; //方位角
                double[] satPos = new double[3] { satellite.Orbit.RealECFPV.X, satellite.Orbit.RealECFPV.Y, satellite.Orbit.RealECFPV.Z };
                double[] userPos = new double[3] { _Parent.Pos_XYZ.X, Parent.Pos_XYZ.Y, Parent.Pos_XYZ.Z };
                SatPredictStatus tempSatStatus = new SatPredictStatus();///新建对象后，可见性Visible默认为false
                tempSatStatus.SatType = satellite.Parent.ConstellationFeature.ConstellationType;
                tempSatStatus.PRN = satellite.Id;
                tempSatStatus.satName = satellite.Name;
                tempSatStatus.Visible = true;
                CalEleAziDLL.Cal_EleAzi(userPos, satPos, ref Ele, ref Azi);
                tempSatStatus.PosX = satPos[0];
                tempSatStatus.PosY = satPos[1];
                tempSatStatus.PosZ = satPos[2];
                tempSatStatus.Elevation = Ele;
                tempSatStatus.Azimuth = Azi;
                if (Ele < Elelim)
                {
                    tempSatStatus.Visible = false;
                }
                else
                {
                    tempSatStatus.PseudoRange = Con_SingleTimAllSatsObsDic[satellite.Parent.ConstellationFeature.ConstellationType][satellite.Name][0].SatObs.A_Pseudo_writein; ;//显示第一个频点的伪距观测数据值
                    tempSatStatus.Phase = Con_SingleTimAllSatsObsDic[satellite.Parent.ConstellationFeature.ConstellationType][satellite.Name][0].SatObs.A_Carri_writein;//显示第一个频点的载波相位观测数据值
                }
                SatSpaceParamList.Add(tempSatStatus);
            }
        }
        #endregion

        #endregion

        public override string ToString()
        {
            return Parent.Name + "<" + this.Name + ">";
        }
    }
}
